/**
 * Copyright (C) 2008 aileron.cc
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package cc.aileron.wsgi.context;

import static com.google.inject.Scopes.SINGLETON;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Provider;

/**
 * ContextProvider
 * 
 * @author Aileron
 * 
 */
public class ContextProvider
{
    /**
     * HttpServletRequest provider
     * 
     * @author Aileron
     * 
     */
    static final Provider<HttpServletRequest> request = new Provider<HttpServletRequest>()
    {
        public HttpServletRequest get()
        {
            return HttpThreadLocalContext.localContext.get().request;
        }
    };

    /**
     * HttpServletResponse provider
     * 
     * @author Aileron
     * 
     */
    static final Provider<HttpServletResponse> response = new Provider<HttpServletResponse>()
    {
        public HttpServletResponse get()
        {
            return HttpThreadLocalContext.localContext.get().response;
        }
    };

    /**
     * context-provider process
     */
    static final Provider<WsgiProcessContext> process = new ContextProviderProcess();

    /**
     * context-provider session
     */
    static final Provider<WsgiSessionContext> session = new ContextProviderSession();

    /**
     * module
     */
    private static final Module module = new Module()
    {
        public void configure(final Binder binder)
        {
            binder.bind(WsgiProcessContext.class).toProvider(process);
            binder.bind(WsgiSessionContext.class).toProvider(session);
            binder.bind(WsgiApplicationContext.class).toProvider(
                    ContextProviderApplication.class).in(SINGLETON);
            binder.bind(WsgiViewContext.class).to(WsgiViewContextImpl.class)
                    .in(SINGLETON);

            binder.bind(HttpServletRequest.class).toProvider(request);
            binder.bind(HttpServletResponse.class).toProvider(response);
            binder.bind(ServletResponse.class).toProvider(response);
            binder.bind(ServletRequest.class).toProvider(request);
        }
    };

    /**
     * destroy
     */
    public static void destroy()
    {
        HttpThreadLocalContext.localContext.set(null);
    }

    /**
     * @return module
     */
    public static Module module()
    {
        return module;
    }

    /**
     * @return process-context
     */
    public static WsgiProcessContext process()
    {
        return process.get();
    }

    /**
     * @return session-context
     */
    public static WsgiSessionContext session()
    {
        return session.get();
    }

    /**
     * setup
     * 
     * @param request
     * @param response
     */
    public static void setup(final HttpServletRequest request,
            final HttpServletResponse response)
    {
        HttpThreadLocalContext.localContext.set(new HttpThreadLocalContext(
                request, response));
    }
}